<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { ElMessageBox, FormInstance, FormRules, ElMessage } from "element-plus";
import type { UploadUserFile, UploadProps } from "element-plus"
import { useRouter } from "vue-router"
import { VxeTablePropTypes } from "vxe-table";
import SelectTag from "@@/components/SelectTag/index.vue"
import { BasicDataInfo, MethodField, SaveRequestData } from "@@/apis/component/type";
import { getModelSearch, saveModelField } from "@@/apis/component";
import { cloneDeep } from "lodash-es";
import { v4 as uuidv4 } from "uuid";
import componentVue from "./components/component.vue"
import FieldTable from "./components/FieldTable.vue"
import StaticFieldTable from "./components/FieldTable.vue"
import XEUtils from "xe-utils";
import "@@/components/plugins/EditDownModal"
import { BasicClassValueField } from "@@/apis/basic-data/types";
import fileList from "./components/fileList.vue"


const router = useRouter()
defineOptions({
  name: "ComponentCreate"
})

const component = ref<BasicDataInfo>({
  name: "",
  code: "",
  tag: "",
  parentId: "",
  description: ""
});
const insertFiles = ref<UploadUserFile[]>([]) // 附件

const rules = ref<FormRules>({
  code: [
    { required: true, message: '请输入', trigger: "blur" },
    { message: "第一个字符必须是字母（大小写均可）或下划线 _", pattern: /^[a-zA-Z_][a-zA-Z0-9_]*$/, trigger: "blur" }
  ],
  name: [{ required: true, message: "请输入别名", trigger: "blur" }],
});
const activeTab = ref("table");
const methodTableData = ref<MethodField[]>([]);
const componentRef = ref<FormInstance | null>(null);
const parentOptions = ref<{ label: string; value: string; code: string }[]>([])
const fieldTableRef = ref()
const staticFieldTableRef = ref()
const methodTableRef = ref()
const table_toolbar = ref("insertStaticFields");

const tableData = ref<BasicClassValueField[]>([]);
const staticTableData = ref<BasicClassValueField[]>([]);
// 页面新增class参数信息
const insertMethods = ref<MethodField[]>([]);
const removeMethods = ref<MethodField[]>([]);

const DEFAULT_METHOD_VALUE: MethodField = {
  type: undefined,
  // 返回值类型
  returnType: undefined,
  // 函数名
  name: undefined
}
const methodsValidRules = ref<VxeTablePropTypes.EditRules>({
  name: [{ required: true, message: '函数名不能为空', trigger: "blur" }],
  type: [{ required: true, message: '函数类型不能为空', trigger: "blur" }],
  returnType: [{ required: true, message: '返回值类型', trigger: "blur" }]
})

const deleteMethodBtn = computed(() => {
  if (methodTableRef.value) {
    const selectRecords = methodTableRef.value.getCheckboxRecords()
    return selectRecords.length > 0
  }
  return false
})

// 新增成员函数
const handleCreateMethod = () => {
  const record = cloneDeep(DEFAULT_METHOD_VALUE)
  record.id = uuidv4()
  methodTableData.value.push(record)
  insertMethods.value.push(record)
  methodTableRef.value.setEditRow(record, 'type');
}
// 批量删除成员函数
const handleMulDelMethod = () => {
  if (methodTableRef.value) {
    const selectRecords = methodTableRef.value.getCheckboxRecords()
    const ids: string[] = []
    const names: string[] = []
    selectRecords.forEach((item) => {
      ids.push(item.id as string)
      names.push(item.name as string)
    })
    ElMessageBox.confirm(`正在删除成员函数：${names.join("，")}，确认删除？`, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    }).then(() => {
      const delIds: number[] = []
      XEUtils.eachTree(selectRecords, item => {
        if (!removeMethods.value.some(obj => item.id === obj.id)) {
          delIds.push(item.id)
          removeMethods.value.push(item)
        }
      }, { children: 'children' })
      methodTableData.value = methodTableData.value.filter(item => !delIds.includes(item.id))
    })
  }
}

const handleTopCreateTask = () => {
  if (table_toolbar.value === 'insertFields') {
    fieldTableRef.value.handleAddDialog()
  }
  if (table_toolbar.value === 'insertStaticFields') {
    staticFieldTableRef.value.handleAddDialog()
  }
}
// 获取组件模型列表
// 获取组件模型列表
onMounted(() => {
  getModelSearch({}).then(({ data }) => {
    parentOptions.value = data.rows.filter(item => item.name && item.id)
      .map((item) => ({
        label: item.name!,
        code: item.code,
        value: item.id!
      }))
  })
})
// 保存
// 提交
const handleSave = async () => {
  if (!componentRef.value) return false
  await fieldTableRef.value.handleValidParam();
  await staticFieldTableRef.value.handleValidParam();

  componentRef.value.validate().then(() => {
    const fieldParam = fieldTableRef.value.getFieldParam()
    const staticFieldParam = staticFieldTableRef.value.getFieldParam()
    const _methodTableData = cloneDeep(methodTableData.value)
    _methodTableData.forEach(item => {
      delete item.id
    })
    const compItem = cloneDeep(component.value)
    compItem.tag = JSON.stringify(compItem.tag)
    let saveData: SaveRequestData = {
      component: cloneDeep(compItem),
      insertFields: fieldParam.insertFields,
      updateFields: [],
      removeFields: [],
      insertStaticFields: staticFieldParam.insertFields,
      updateStaticFields: [],
      removeStaticFields: [],
      insertMethods: _methodTableData,
      updateMethods: [],
      removeMethods: [],
    }
    const fd = new FormData()
    insertFiles.value.forEach((item: any, index: any) => {
      fd.append(`insertFiles[${index}].file`, item.raw)
    })
    fd.append("businessParam", JSON.stringify(saveData))
    saveModelField(fd).then((res) => {
      ElMessage.success("保存成功")
      handleCancel()
    }).catch(() => {
      ElMessage.error("保存失败")
    })
  })
    .catch(() => {
      return false
    })
}
// 退出
const handleCancel = () => {
  router.replace({ name: 'ComponentIndex' })
}
const handleFileChange: UploadProps["onChange"] = (file: any, fileList: any) => {
  insertFiles.value.push(file)
}
// 删除节点
const removeNode = (id: string) => {
  if (table_toolbar.value === 'insertFields') {
    fieldTableRef.value.handleRemoveNode(id)
  }
  if (table_toolbar.value === 'insertStaticFields') {
    staticFieldTableRef.value.handleRemoveNode(id)
  }
}
const handleChangeToolbar = (value: string) => {
  table_toolbar.value = value
}
const updateData = (params: BasicClassValueField[]) => {
  tableData.value = cloneDeep(params)
}
const updateStaticData = (params: BasicClassValueField[]) => {
  staticTableData.value = cloneDeep(params)
}
const handleEditDialog = (data: BasicClassValueField) => {
  if (table_toolbar.value === 'insertFields') {
    fieldTableRef.value.handleEditDialog(data)
  }
  if (table_toolbar.value === 'insertStaticFields') {
    staticFieldTableRef.value.handleEditDialog(data)
  }
}
</script>

<template>
  <div class="app-container pager-container">
    <div class="app-container-content">
      <div class="cpi-header">
        <span class="cpi-header-text">基本信息</span>
      </div>
      <div class="basic-data-create-table">
        <el-form ref="componentRef" :model="component" status-icon :rules="rules" label-position="right" label-width="85"
          class="demo-basicData">
          <el-row :gutter="24">
            <el-col :sm="12" :lg="6">
              <el-form-item label="名称" prop="code">
                <el-input v-model="component.code" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6">
              <el-form-item label="别名" prop="name">
                <el-input v-model="component.name" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6">
              <el-form-item label="标签" prop="tag">
                <SelectTag module="component" v-model:task_tags="component.tag" :max-collapse-tags="2" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6">
              <el-form-item label="父类" prop="parentId">
                <el-select v-model="component.parentId" filterable placeholder="请选择" style="width: 100%">
                  <el-option v-for="item in parentOptions" :key="item.value" :label="`${item.label}/${item.code}`"
                    :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :sm="24" :lg="12">
              <el-form-item label="描述">
                <el-input v-model="component.description" type="textarea" show-word-limit placeholder="请输入"
                  autocomplete="off" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <div class="cpi-header">
        <span class="cpi-header-text">参数集</span>
        <span class="cpi-header-text-right">
          <span class="cpi-header-text-right-text" @click="activeTab = 'table'"
            :class="{ active: activeTab === 'table' }">表格</span>
          <span class="cpi-header-text-right-text" @click="activeTab = 'topology'"
            :class="{ active: activeTab === 'topology' }">拓扑</span>
        </span>
      </div>
      <div class="cpi-content" v-show="activeTab === 'table'">
        <div class="table_toolbar">
          <span :class="{ active: table_toolbar === 'insertStaticFields' }"
            @click="() => table_toolbar = 'insertStaticFields'">
            静态参数集
          </span>
          <span :class="{ active: table_toolbar === 'insertFields' }"
            @click="() => table_toolbar = 'insertFields'">属性集</span>
        </div>

        <FieldTable v-show="table_toolbar === 'insertFields'" ref="fieldTableRef" :static-flag="0" :is-edit="true"
          @updateData="updateData" />
        <StaticFieldTable v-show="table_toolbar === 'insertStaticFields'" ref="staticFieldTableRef" :static-flag="1"
          :is-edit="true" @updateData="updateStaticData" />
      </div>

      <div class="cpi-content" v-if="activeTab === 'topology'">
        <componentVue :handleCreateTask="handleTopCreateTask" :table_toolbar_clk="handleChangeToolbar"
          :table_toolbar="table_toolbar" :fatherData="table_toolbar === 'insertFields' ? tableData : staticTableData"
          :adminUser="component.code" :handleRemoveNode="removeNode" :handleEdit="handleEditDialog" />
      </div>

      <div class="cpi-header" style="margin-top: var(--main-padding);">
        <span class="cpi-header-text">成员函数</span>
      </div>
      <div class="cpi-content">
        <div class="cpi-content-toolbar mb-3">
          <el-space>
            <el-button type="primary" plain @click="handleCreateMethod()">新建函数</el-button>
            <el-button :disabled="!deleteMethodBtn" type="danger" @click="handleMulDelMethod">批量删除</el-button>
          </el-space>
        </div>
        <div class="cpi-content-main">
          <vxe-table class="cpi-table" ref="methodTableRef" height="auto" show-overflow highlight-hover-row show-header
            auto-resize keep-source size="small" :edit-rules="methodsValidRules" :data="methodTableData"
            :mouse-config="{ selected: false }" :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }">
            <vxe-table-column type="checkbox" width="40" />
            <vxe-table-column type="seq" title="序号" align="center" width="60" />
            <vxe-table-column field="type" title="类型">
              <template #default="{ row }">
                <el-select v-model="row.type" placeholder="请选择">
                  <el-option v-for="item in ['static', 'virtual', 'normal']" :key="item" :label="item" :value="item" />
                </el-select>
              </template>
            </vxe-table-column>
            <vxe-table-column field="returnType" title="返回类型">
              <template #default="{ row }">
                <el-input v-model="row.returnType" />
              </template>
            </vxe-table-column>
            <vxe-table-column field="name" title="函数名称">
              <template #default="{ row }">
                <el-input v-model="row.name" />
              </template>
            </vxe-table-column>
          </vxe-table>
        </div>
      </div>
      <div class="cpi-header">
        <span class="cpi-header-text">附件</span>
      </div>
      <div>
        <el-upload class="again-upload" :show-file-list="true" action="https://your-api.com/uploadList" ref="upload" :file-list="insertFiles"
          accept=".zip, .pdf, .doc .docx" @change="handleFileChange" :multiple="true">
          <el-button type="success">
            添加附件
          </el-button>
        </el-upload>
      </div>
    </div>
    <div class="pager-wrapper center">
      <el-button type="primary" @click="handleSave">保存</el-button>
      <el-button @click="handleCancel">退出</el-button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import "@@/assets/styles/mixins.scss";

.app-container-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 10px;
  @extend %scrollbar;
}

.bac-tabs {
  :deep(.el-tabs__item:hover) {
    color: #409eff !important;
  }

  :deep(.el-tabs__item.is-active:hover) {
    color: white;
  }

  :deep(.el-tabs__item.is-active) {
    background-color: #409eff !important;
    color: white !important;
  }
}

.basic-data-create-footer {
  position: fixed;
  bottom: 0;
  height: 50px;
  left: 0;
  right: 0;
  z-index: 1000;
  width: calc(100vw - 250px);
  background: #000B15;
  display: flex;
  margin-left: 218px;
  justify-content: center;
  align-items: center;
  // margin-top: 20px;
}

.table_toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  height: 40px;

  span {
    height: 100%;
    flex: 1;
    text-align: center;
    line-height: 40px;
    border: 1px solid var(--el-border-color-light);
    cursor: pointer;

    &:hover {
      color: #409eff !important;
    }
  }

  span.active {
    background-color: #409eff !important;
    color: white;
  }
}

.cpi-content {
  min-height: 500px;
  display: flex;
  flex-direction: column;
  .cpi-content-main {
    width: 100%;
    height: 100%;
  }
}
</style>
